#include "uart4.h"

//串口初始化
void uart4_init()
{

    //使能UART4外设时钟
    RCC->MP_APB1ENSETR |= (0x1<<16);
    //使能GPIOB/GPIOG外设时钟
    RCC->MP_AHB4ENSETR |= (0x1<<1);
    RCC->MP_AHB4ENSETR |= (0x1<<6);

    //设置PB2/PG11复用为UART4功能
    //PB2
    GPIOB->MODER &= (~(0x3<<4));
    GPIOB->MODER |= (0x2<<4);
    GPIOB->AFRL &= (~(0xf<<8));
    GPIOB->AFRL |= (0x8<<8);
    //PG11
    GPIOG->MODER &= (~(0x3<<22));
    GPIOG->MODER |= (0x2<<22);
    GPIOG->AFRH &= (~(0xf<<12));
    GPIOG->AFRH |= (0x6<<12);

    //禁用串口UE=0
    USART4->CR1 &= (~(0x1<<0));
    //设置8bit数据位
    USART4->CR1 &= (~(0x1<<12));
    USART4->CR1 &= (~(0x1<<28));
    //设置没有校验位
    USART4->CR1 &= (~(0x1<<10));
    //设置不分频
    USART4->PRESC &= (~(0xf<<0));
    //设置16倍过采样
    USART4->CR1 &= (~(0x1<<15));
    //设置1bit停止位
    USART4->CR2 &= (~(0x3<<12));
    //设置115200波特率
    USART4->BRR =0x22b;
    //使能发送器
    USART4->CR1 |= (0X1<<3);
    //使能接收器
     USART4->CR1 |= (0X1<<2);
    //使能串口
    USART4->CR1 |= 0x1;

}
//封装单个字符的发送函数
void putchar(char ch)
{
    //判断发送数据寄存器是否为空
    //不为空则等待
    while (!(USART4->ISR&(0x1<<7)));
    //为空。向发送数据寄存器写入
    USART4->TDR=ch;
    //等待送完成
    while (!(USART4->ISR&(0x1<<6))); 
}

//单个字符的接收
char getchar()
{
    //判断接收数据寄存器是否有数据
    //没有数据则等待
    while (!(USART4->ISR&(0x1<<5)));
    
    //有数据就将数据读取返回
    return USART4->RDR;
}


//封装字符串的输入
void gets(char *s)
{
    //循环调用单个字符接收
    //等待读取到回车键\r，字符串接收
       
    //判断发送数据寄存器是否为空
    //不为空则等待
    while (!(USART4->ISR&(0x1<<7)));
    //为空。向发送数据寄存器写入
    USART4->TDR=ch;
    //等待送完成
    while (!(USART4->ISR&(0x1<<6)));

}

//字符串输出
void puts(char *s)
{
    //循环调用单个字符的发送
    //直到遇到\0结束
    //最后末尾发送一个换行一个回车

    //判断接收数据寄存器是否有数据
    //没有数据则等待
    while (!(USART4->ISR&(0x1<<5)));
    
    //有数据就将数据读取返回
    return USART4->RDR;
}